home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
dos6mm.zip
/
REMOVE.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-03-31
|
18KB
|
368 lines
;****************************************************************************
; REMOVE removes a bookmark placed in memory by INSTALL. Its syntax is:
;
; REMOVE [bookmark] [/L]
;
; where "bookmark" is the name of the bookmark to be removed from memory,
; and /L lists the bookmarks that are currently resident in memory. When
; a bookmark is removed, all the TSRs installed above it are removed also.
; Run with no command line parameters, REMOVE removes the highest bookmark
; in memory.
;****************************************************************************
nextblock equ 0103h ;Offset of NEXTBLOCK field
bm_addr equ 0105h ;Offset of bookmark field
vectors equ 0133h ;Offset of vector field
code segment
assume cs:code,ds:code
org 100h
begin: jmp main
helpmsg db "Removes a bookmark created with INSTALL."
db 13,10,13,10
db "REMOVE [bookmark] [/L]",13,10,13,10
db " bookmark Name of the bookmark to remove.",13,10
db " /L List the bookmarks currently "
db "installed.",13,10,13,10
db "Run with no parameters, REMOVE removes the most "
db "recently installed bookmark.",13,10
db "When a bookmark is removed, all the TSRs installed "
db "after it are removed, too.",13,10,"$"
errmsg1 db "Syntax: REMOVE [bookmark] [/L]",13,10,"$"
errmsg2 db "Requires DOS 3.0 or higher",13,10,"$"
errmsg3 db "There are no bookmarks installed",13,10,"$"
errmsg4 db "There is no bookmark by that name",13,10,"$"
errmsg5 db "Memory deallocation failed",13,10,"$"
msg1 db "REMOVE 1.3 Copyright (c) 1993 Jeff Prosise",13,10
db "From: PC Magazine DOS 6 Memory Management "
db "with Utilities",13,10,13,10
db "Bookmark $"
msg2 db " removed"
crlf db 13,10,"$"
lastblock dw ? ;Segment of last block
bookmark db 33 dup (0Dh) ;Bookmark name
signature db 0,1,2,"INSTALL",2,1,0 ;INSTALL signature
;****************************************************************************
; Procedure MAIN
;****************************************************************************
main proc near
cld ;Clear direction flag
mov si,81h ;Point SI to command line
call scanhelp ;Scan for "/?" switch
jnc checkver ;Branch if not found
mov ah,09h ;Display help text and exit
mov dx,offset helpmsg ;with ERRORLEVEL=0
int 21h
mov ax,4C00h
int 21h
;
; Check the DOS version.
;
checkver: mov dx,offset errmsg2 ;Exit if DOS version
mov ah,30h ;is less than 3.0
int 21h
cmp al,3
jae checkins
error: mov ah,09h ;Display error message and
int 21h ;exit with ERRORLEVEL=1
mov ax,4C01h
int 21h
checkins: call check_install ;See if INSTALL is installed
mov dx,offset errmsg3
jnc error ;Exit if it's not
;
; Parse the command line.
;
mov lastblock,cs ;Initialize LASTBLOCK
mov si,81h ;Reset SI
call findchar ;Find the first parameter
jc search1 ;Branch if there are none
cmp byte ptr [si],"/" ;Branch if the character
jne parse ;is not a "/"
;
; Process a /L switch.
;
list: inc si ;Skip the "/" character
lodsb ;Get the next character
and al,0DFh ;Capitalize it
mov dx,offset errmsg1 ;Initialize error pointer
cmp al,"L" ;Error if the character is
jne error ;not an "L"
nextname: mov di,bm_addr ;Point DI to bookmark name
call dos_out ;Display bookmark name
mov ah,09h ;Move the cursor to the
mov dx,offset crlf ;next line
int 21h
cmp word ptr es:[nextblock],0FFFFh ;Exit if this is the
je list_exit ;last block
mov es,es:[nextblock] ;Get segment of next block
jmp nextname ;Go back and output its name
list_exit: mov ax,4C00h ;Exit with ERRORLEVEL=0
int 21h
;
; Read the bookmark name from the command line.
;
parse: mov di,offset bookmark ;Point DI to buffer
mov cx,32 ;Initialize counter
parse1: lodsb ;Get a character
cmp al,"a" ;Capitalize it if it's
jb parse2 ;between "a" and "z"
cmp al,"z"
ja parse2
and al,0DFh
parse2: mov [di],al ;Store it
inc di ;Increment DI
cmp al,0Dh ;Branch if it was a carriage
je search ;return
loop parse1 ;Loop back for more
;
; Search out a bookmark.
;
search: mov si,offset bookmark ;Point SI to local name
mov di,bm_addr ;Point DI to remote name
call compare_names ;Compare the two
je endchain ;Branch if they're equal
mov dx,offset errmsg4
cmp word ptr es:[nextblock],0FFFFh
je error ;Error if last block
mov lastblock,es ;Save last block address
mov es,es:[nextblock] ;Get address of next block
jmp search ;Return to search loop
search1: cmp word ptr es:[nextblock],0FFFFh
je endchain ;Branch if last block
mov lastblock,es ;Save last block address
mov es,es:[nextblock] ;Get address of next block
jmp search1 ;Continue the search
;
; Terminate the chain of INSTALLed blocks and restore interrupt vectors.
;
endchain: push es ;Save ES
mov es,lastblock ;Retrieve last block address
mov word ptr es:[nextblock],0FFFFh ;Terminate the chain
pop es ;Restore ES
mov lastblock,es ;Save ES in LASTBLOCK
push ds ;Save DS and ES
push es
mov ax,es ;Point DS:SI to copy of
mov ds,ax ;interrupt vectors in
assume ds:nothing ;INSTALLed block
mov si,vectors
sub di,di ;Point ES:DI to 0000:0000
mov es,di
mov cx,512 ;Initialize counter
cli ;Disable interrupts
rep movsw ;Restore interrupt vectors
sti ;Enable interrupts
pop es ;Restore DS and ES
pop ds
assume ds:code
;
; Search out every PSP block above INSTALL and deallocate the memory that
; belongs to it.
;
mov bx,es ;Transfer ES to BX
mov ah,49h ;Deallocate the memory used
int 21h ;by INSTALL
mov dx,offset errmsg5 ;Initialize error pointer
jc error1 ;Error if call failed
remove: dec bx ;Point BX to MCB
mov es,bx ;Transfer BX to ES
add bx,es:[03h] ;Compute next MCB address
inc bx
mov es,bx ;Transfer segment to ES
inc bx ;Point BX to segment beyond
cmp bx,es:[01h] ;Does the segment own itself?
jne remove ;No, then continue searching
mov ax,cs ;Record current segment in AX
cmp bx,ax ;Have we reached our own PSP?
je done ;Yes, then we're done
push bx ;Save PSP segment address
call freemem ;Free all memory it owns
pop bx ;Retrieve the address
mov dx,offset errmsg5 ;Loop back if no error
jnc remove ;occurred
error1: jmp error ;Exit on error
;
; Announce that REMOVE succeeded and terminate.
;
done: mov ah,09h ;Display message verifying
mov dx,offset msg1 ;that the book mark was
int 21h ;removed
mov es,lastblock
mov di,bm_addr
call dos_out
mov ah,09h
mov dx,offset msg2
int 21h
mov ax,4C00h ;Exit with ERRORLEVEL=0
int 21h
main endp
;****************************************************************************
; FINDCHAR advances SI to the next non-white-space character. On return,
; carry set indicates EOL was encountered.
;****************************************************************************
findchar proc near
lodsb ;Get the next character
cmp al,09h ;Loop if tab
je findchar
cmp al,20h ;Loop if space
je findchar
cmp al,2Ch ;Loop if comma
je findchar
dec si ;Point SI to the character
cmp al,0Dh ;Exit with carry set if end
je eol ;of line is reached
clc ;Clear carry and exit
ret
eol: stc ;Set carry and exit
ret
findchar endp
;****************************************************************************
; SCANHELP scans the command line for a /? switch. If found, carry returns
; set and SI contains its offset. If not found, carry returns clear.
;****************************************************************************
scanhelp proc near
push si ;Save SI
scanloop: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,"?" ;Loop if not "?"
jne scanloop
cmp byte ptr [si-2],"/" ;Loop if not "/"
jne scanloop
add sp,2 ;Clear the stack
sub si,2 ;Adjust SI
stc ;Set carry and exit
ret
scan_exit: pop si ;Restore SI
clc ;Clear carry and exit
ret
scanhelp endp
;****************************************************************************
; CHECK_INSTALL returns carry set if a copy of INSTALL is installed,
; carry clear if it's not. If carry returns set, AH holds INSTALL's
; multiplex ID number and ES holds its segment address.
;****************************************************************************
check_install proc near
mov ax,0C000h ;Initialize AH and AL
mov cx,40h ;Initialize count
chinst1: push ax ;Save AX and CX
push cx
sub di,di ;Set ES and DI to 0
mov es,di
int 2Fh ;Interrupt 2Fh
cmp al,0FFh ;Nothing here if AL isn't
jne chinst2 ;equal to FFH
mov si,offset signature ;See if program signature
mov cx,13 ;appears at the address
repe cmpsb ;returned in ES:DI
jne chinst2 ;Branch if it does not
pop cx ;Clear the stack and exit
pop ax ;with carry set
stc
ret
chinst2: pop cx ;Retrieve AX and CX
pop ax
inc ah ;Next multiplex ID
loop chinst1 ;Loop until done
clc ;Exit with carry clear
ret
check_install endp
;****************************************************************************
; FREEMEM frees all the memory blocks owned by the process whose PSP
; address is passed in BX. Carry is set on return if a call to release
; a block of memory failed.
;****************************************************************************
freemem proc near
push bx ;Save BX
mov ah,52h ;Get address of the first
int 21h ;MCB with DOS function 52H
mov dx,es:[bx-2] ;Copy the address to DX
mov es,dx ;Also copy it to ES
pop bx ;Restore BX
free1: cmp bx,es:[01h] ;Branch if the ownership
jne free2 ;word does not match
inc dx ;Increment DX
mov es,dx ;Point ES to segment
mov ah,49h ;Deallocate the segment
int 21h
jc free_exit ;Exit if called failed
dec dx ;Decrement DX
mov es,dx ;Point ES back to the MCB
free2: add dx,es:[03h] ;Compute the address of the
inc dx ;next MCB
mov es,dx ;Transfer address to ES
cmp byte ptr es:[00h],"Z" ;End of the MCB chain?
jne free1 ;No, then continue the search
clc ;Clear carry and exit
free_exit: ret
freemem endp
;****************************************************************************
; COMPARE_NAMES compares the two ASCII strings addressed by DS:SI and ES:DI.
; On return, the Z flag indicates whether or not the two are equal.
;****************************************************************************
compare_names proc near
lodsb ;Get a character
cmp al,0Dh ;Exit if it's a carriage
je compare_exit ;return
scasb ;Compare it ES:[DI]
je compare_names ;Loop back if they're euqal
compare_exit: ret ;Return to caller
compare_names endp
;****************************************************************************
; DOS_OUT displays the ASCII string pointed to by ES:DI.
;****************************************************************************
dos_out proc near
mov dl,es:[di] ;Get a character
cmp dl,0Dh ;Exit if it's a carriage
je dos_exit ;return
mov ah,02h ;Output it using DOS
int 21h ;function 02H
inc di ;Advance DI to next one
jmp dos_out ;Loop until done
dos_exit: ret
dos_out endp
code ends
end begin